package main

import (
	"github.com/streadway/amqp"
	"log"
	"net/url"
	"fmt"
	//"errors"
	//"gorm.io/gorm"
	"github.com/jinzhu/gorm"
	_"github.com/go-sql-driver/mysql"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Stu_course struct {
	ID      		int			`gorm:"primaryKey"`
	Stu_id			string
	Course_id		string
}
//数据库中表名必须为该模型的复数：dorms
type Course struct{
	ID      		int			`gorm:"primaryKey"`
	Course_id 		string
	Course_name		string
	Course_time		string
	Course_place	string
	Course_nums		int
}

func parseurl(s string){
	u, err := url.Parse(s)
	if err != nil {
		panic(err)
	}
	//fmt.Println(u.RawQuery)
	m, _ := url.ParseQuery(u.RawQuery)
	fmt.Println(m)
	//处理请求
	Core(m.Get("stu_id"),m.Get("course_id"))
}

func Core(stu_id string,course_id string) {
	dsn := "Benson:123456@tcp(127.0.0.1:3306)/course_selection?charset=utf8mb4&parseTime=True&loc=Local"
	//连接数据库
	db, err := gorm.Open("mysql",dsn)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("------------连接数据库成功-----------")
	//由于在php中已经判断了参数的合法性，这里的参数都合法
	//已知学生的学号stu_id和该学生选择的课程号course_id
	stu_course :=Stu_course{Stu_id: stu_id,Course_id: course_id}
	course :=Course{}
	// 开始事务
	tx := db.Begin()
		//插入一条数据
		err1 := tx.Create(&stu_course).Error
		if(err1 != nil){
			tx.Rollback()
		}
		//更新数据 (如果不加Where，更新的是数据库中表的某一列所有值)
		err2:=tx.Model(&course).Where("course_id = ?",course_id).Update("course_nums",gorm.Expr("course_nums- ?", 1)).Error
		if(err2 != nil){
			tx.Rollback()
		}	
	// 否则，提交事务
	tx.Commit()
	fmt.Printf("stu_id:%s course_id:%s 选课成功\n",stu_id,course_id) 
}

func main(){
	// 连接RabbitMQ服务器
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()
	// 创建一个channel
	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()
	// 监听队列
	q, err  := ch.QueueDeclare(
		"hello",			// 队列名称
		false,			// 是否持久化
		false,		// 是否自动删除
		false,			// 是否独立
		false,
		nil,
	)
	failOnError(err, "Failed to declare a queue")
	// 消费队列
	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	failOnError(err, "Failed to register a consumer")
	// 申明一个goroutine,一遍程序始终监听
	forever := make(chan bool)

	go func() {
		for d := range msgs {
			log.Printf("Received a message: %s", d.Body)
			parseurl(string(d.Body))
		}
	}()

	log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
	<-forever
}

// 帮助函数检测每一个amqp调用
func failOnError(err error, msg string)  {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}
